#pragma once
#include <type_traits>
template<bool>
inline static void _DEL(void*);

#include <Unknwn.h>
template<>
void _DEL<true>(void* p)
{
	((IUnknown*)p)->Release();
}

template<>
void _DEL<false>(void* p)
{
	delete[] p;
}



template<typename T>
inline static void _RELEASE(T*& p)
{
	if (p)
	{
		_DEL<std::is_base_of<IUnknown, T>::value>(p);
		p = nullptr;
	}
}


#include <fstream>
template<>
void _RELEASE<std::ofstream>(std::ofstream*& p)
{
	if (p)
	{
		p->close();
		delete p;
		p = nullptr;
	}
}


#include <stack>
class _COM_RELEASE_
{
	std::stack<IUnknown*> _M_stack;
public:
	_COM_RELEASE_() = default;
	~_COM_RELEASE_()
	{
		while (!_M_stack.empty())
		{
			_M_stack.top()->Release();
			_M_stack.pop();
		}
	}

	template<typename T>
	void push(T* ptr)
	{
		_M_stack.push((IUnknown*)ptr);
	}

};